package com.jysz.certificate.service.mf;


import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import com.jysz.certificate.persistence.dao.mf.BillDao;
import com.jysz.certificate.persistence.dao.mf.BillOptionDao;
import com.jysz.certificate.persistence.dao.system.FinancialDao;
import com.jysz.certificate.persistence.enums.mf.BillStatus;
import com.jysz.certificate.persistence.model.mf.BillOption;
import com.jysz.certificate.persistence.model.pm.PerformanceAssign;
import com.jysz.certificate.persistence.model.system.Shop;
import com.jysz.certificate.utils.DateUtil;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;
import com.jysz.webcore.ssh.service.EntityService;

/**
 * 发票Service
 * @author xuxiaolong
 */
@Service
public class BillOptionService extends EntityService<BillOption, Long, BillOptionDao> {

	@Override
	public BillOptionDao getEntityDao() {
		return this.optionDao;
	}

	@Resource
	private BillDao billDao;
	@Resource
	private BillOptionDao optionDao;
	@Resource
	private FinancialDao financialDao;
	
	public List<BillOption> getBillOptionList(PerformanceAssign entity){
		Criteria criteria =  this.getEntityDao().createCriteria();
		criteria.createCriteria("paShopMonthDetail").createCriteria("performanceAssignShopDetail").add(Restrictions.eq("performanceAssign", entity));
		criteria.add(Restrictions.eq("hasAssigned", true));
		return criteria.list();
	}
	 
	public Page<BillOption> billOptionFinadPage(Long billId,String shopName,int pageNumber,int pageSize){
		Criteria criteria = optionDao.createCriteria();
		criteria.createCriteria("bills").add(Restrictions.eq("id",billId));
		if (StringUtils.isNotBlank(shopName)) {
			criteria.createCriteria("shop").add(Restrictions.like(Shop.COLUMN_SHOP_NAME, shopName, MatchMode.START));
		}
		return findPage(criteria, pageNumber, pageSize);
	}
	
	/**
	 * 查找同一个申请单下，同一个店铺下的明细
	 * @author xuxiaolong
	 * @param billApplyId
	 * @param shopId
	 * @return
	 */
	public List<BillOption> findOptionsByApply(Long billApplyId,Long shopId){
		Criteria criteria = optionDao.createCriteria();
		Criteria billsCriteria=criteria.createCriteria("bills");
		billsCriteria.createCriteria("billApply").add(Restrictions.eq("id", billApplyId));
		billsCriteria.createCriteria("shop").add(Restrictions.eq("id", shopId));
		
		return criteria.list();
	}
	
	public boolean keyBillOpention(Long shopId,String month,Long financialId){
		Criteria criteria = optionDao.createCriteria();
		criteria.createCriteria("shop").add(Restrictions.eq("id", shopId));
		criteria.createCriteria("financial").add(Restrictions.eq("id", financialId));
		criteria.add(Restrictions.eq("month", month));
		List<BillOption> billOptions =criteria.list();
		if(billOptions.size()>0){
			return true;
		}
		return false;
	}

	/**
	 * 获得年度总收入,用于图形报表
	 * @author xuxiaolong
	 * @param year
	 * @return
	 */
	public Map<Integer,Double> findIncomeTotal(Integer year){
		
		return optionDao.findIncomeTotal(year);
	}
	
	/**
	 * 获得年度金融机构收入分配,用于图形报表
	 * @author xuxiaolong
	 * @param year
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public Map<String,Double> findIncomeFin(Integer year){
		
		return optionDao.findIncomeFin(year);
	}
	
	/**
	 * 按金融机构统计业务往来的店铺
	 * @author xuxiaolong
	 * @param year
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public LinkedHashMap<String,Integer> findFinShop(Date startDate,Date endDate){
		
		return optionDao.findFinShop(startDate, endDate);
	}
	
	
	/**
	 * 获取所有存在实收发票店铺
	 * @param monthDate
	 */
	public List<Shop> findShopsAtBeforeMonthOfStateCharged(String monthDate) {
		return optionDao.findShopIdsAtBeforeMonthOfStateCharged(monthDate);
	}
	
	/**
	 * 获取这个月份的实收金额。
	 * 
	 * @param monthDate
	 * @param shop
	 * @return
	 */
	public List<BillOption> findBillOptionsAtMonthOfStateCharged(
			String monthDate, Shop shop) {
		return optionDao.findBillOptionsAtMonthOfStateCharged(monthDate, shop);
	}
	public List<String> findShopMonthsAtBeforeMonthOfStateCharged(
			String monthDate, Shop shop) {
		return optionDao.findShopMonthsAtBeforeMonthOfStateCharged(monthDate, shop);
	}
	public List<String> findShopMonthsAtBeforeMonthOfStateCharged(
			String monthDate, List<Shop> shops) {
		return optionDao.findShopMonthsAtBeforeMonthOfStateCharged(monthDate, shops);
	}
	/**
	 * 导出  查询发票明细
	 */
	public List<BillOption> exportBillOptions(Long billId){
		Criteria criteria = optionDao.createCriteria();
		criteria.createCriteria("bills").add(Restrictions.eq("id", billId));
		return criteria.list();
		
	}

	/**
	 * 获取实收月份相关管理费的所有店铺（这个月收了那些店的管理费）
	 * 
	 * @param financialId
	 * @param payMonth
	 * @return
	 */
	public List<BillOption> findShopsAtPayMonth(Long financialId, String payMonth) {
		Criteria criteria = this.getEntityDao().createCriteria();
		criteria.add(Restrictions.eq("financial.id", financialId));
		this.addMonthBetween(payMonth, criteria);
		
		criteria.add(Restrictions.eq("status", BillStatus.CHARGED));
//		Criteria billCriteria = criteria.createCriteria("bills", Criteria.LEFT_JOIN);
		return criteria.list();
	}
	
	/**
	 * @param financialId
	 * @param payMonth
	 * @param month
	 * @return
	 */
	public List<BillOption> findShopsAtPayMonth(Long financialId,
			String payMonth, String month) {
		Criteria criteria = this.getEntityDao().createCriteria();
		
		criteria.add(Restrictions.eq("financial.id", financialId));
		criteria.add(Restrictions.eq("month", month));
		
		this.addMonthBetween(payMonth, criteria);
		
		criteria.add(Restrictions.eq("status", BillStatus.CHARGED));
		criteria.add(Restrictions.ne("amount", 0.0D));
		return criteria.list();
	}
	
	/**
	 * 查询导出所有月份
	 * 
	 * @param financialId
	 * @param payMonth
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<String> findPayExportMonths(Long financialId, String payMonth) {
		Criteria criteria = this.getEntityDao().createCriteria();
		
		criteria.setProjection(Projections.groupProperty("month"));
		
		criteria.add(Restrictions.eq("financial.id", financialId));
		
		this.addMonthBetween(payMonth, criteria);
		
		criteria.add(Restrictions.eq("status", BillStatus.CHARGED));
		criteria.add(Restrictions.ne("amount", 0.0D));
		return criteria.list();
	}

	/**添加实收月份范围
	 * 
	 * @param payMonth
	 * @param criteria
	 */
	public void addMonthBetween(String payMonth, Criteria criteria) {
		Date payMonthDate = DateUtil.getDate(payMonth, "yyyy-MM");
		criteria.add(Restrictions.between("incomeDate", DateUtil.getFirstdayLastdayMonthOne(payMonthDate), DateUtil.getFirstdayLastdayMonth(payMonthDate)));
	}


}
